/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */


package com.android1.amarena2d.nodes.behavior.delegates;

import com.android1.amarena2d.engine.EngineObject;
import com.android1.amarena2d.engine.collision.Collision;
import com.android1.amarena2d.engine.collision.CollisionCallback;
import com.android1.amarena2d.engine.collision.EntityCollisionVolume;
import com.android1.amarena2d.nodes.Entity;
import com.android1.amarena2d.nodes.behavior.Collidable;
import com.android1.amarena2d.nodes.behavior.CollidableEntity;
import com.badlogic.gdx.math.Vector2;

public class EntityCollisionDelegate extends EngineObject implements CollisionDelegate, Collision {

    final CollidableEntity entity;
    final EntityCollisionVolume collisionVolume;

    CollisionCallback onCollisionCallback;
    int checkBehaviour = CheckBehaviour.Active;
    boolean allowMultipleCollisionsPerTick;
    boolean registered;
    boolean notifyOnCollision;
    final Vector2 lastPos = new Vector2();

    public boolean debug;

    public EntityCollisionDelegate(final CollidableEntity entity) {
        this.entity = entity;
        this.lastPos.set(entity.getXY());
        this.collisionVolume = new EntityCollisionVolume(entity);
        this.checkBehaviour = CheckBehaviour.Active;
    }

    @Override
    public Collidable getCollidable() {
        return entity;
    }

    @Override
    public EntityCollisionVolume getVolume() {
        return collisionVolume;
    }

    @Override
    public void onCollision(final CollisionDelegate collisionDelegate) {
        if (onCollisionCallback != null) {
            onCollisionCallback.on(this, collisionDelegate);

        }
    }

    public EntityCollisionDelegate setOnCollision(final CollisionCallback onCollisionCallback) {
        this.onCollisionCallback = onCollisionCallback;
        notifyOnCollision();
        return this;
    }

    public EntityCollisionDelegate setVolumeBox(final float offsetX, final float offsetY, final float width, final float height) {
        collisionVolume.setBoxSize(width, height);
        collisionVolume.setBoxXY(offsetX, offsetY);
        return this;
    }

    public EntityCollisionDelegate adjustVolumeBox(final float offsetX, final float offsetY, final float width, final float height) {
        collisionVolume.setBoxSize(collisionVolume.getBoxSize().width + width, collisionVolume.getBoxSize().height + height);
        collisionVolume.setBoxXY(collisionVolume.getBoxXY().x + offsetX, collisionVolume.getBoxXY().y + offsetY);
        return this;
    }

    public EntityCollisionDelegate notifyOnCollision() {
        this.notifyOnCollision = true;
        return this;
    }

    public EntityCollisionDelegate silentOnCollision() {
        this.notifyOnCollision = false;
        return this;
    }

    public void register() {
        if (!registered) {
            engine.getCollisionManager().register(this);
            registered = true;
        }
    }

    public void unregister() {
        if (registered) {
            engine.getCollisionManager().unregister(this);
            registered = false;
        }
    }

    public EntityCollisionDelegate setCheckBehaviour(int behaviour) {
        this.checkBehaviour = behaviour;
        return this;
    }

    public EntityCollisionDelegate setMultipleCollisionsPerTick(boolean enable) {
        this.allowMultipleCollisionsPerTick = enable;
        return this;
    }

    public Entity getEntity() {
        return entity;
    }

    @Override
    public int getCheckBehaviour() {
        return checkBehaviour;
    }

    @Override
    public void saveLastPos() {
        this.lastPos.set(entity.getXY());
    }

    @Override
    public void revertToLastPos() {
        this.entity.setXY(lastPos.x, lastPos.y);
    }

    @Override
    public boolean isAllowMultipleCollisionsPerTick() {
        return allowMultipleCollisionsPerTick;
    }

    @Override
    public boolean isNotifyOnCollision() {
        return notifyOnCollision;
    }

    @Override
    public boolean isActive() {
        return entity.isActive();
    }
}
